/*
 * Copyright (c) 2018-2999 湖南洛云网络科技有限公司 All rights reserved.
 *
 * https://www.gz-yami.com/
 *
 * 未经允许，不可做商业用途！
 *
 * 版权所有，侵权必究！
 */

package com.yami.shop.user.api.listener;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yami.shop.bean.app.param.PayInfoParam;
import com.yami.shop.bean.enums.BuyType;
import com.yami.shop.bean.event.BalancePayEvent;
import com.yami.shop.bean.model.Order;
import com.yami.shop.bean.model.OrderItem;
import com.yami.shop.bean.model.UserExtension;
import com.yami.shop.bean.pay.PayInfoDto;
import com.yami.shop.common.enums.PayType;
import com.yami.shop.common.i18n.I18nMessage;
import com.yami.shop.common.i18n.LanguageEnum;
import com.yami.shop.common.util.Arith;
import com.yami.shop.service.*;
import com.yami.shop.user.comment.model.UserBalanceLog;
import com.yami.shop.user.comment.service.UserBalanceLogService;
import com.yami.shop.user.comment.service.UserLevelService;
import lombok.AllArgsConstructor;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * 余额支付操作
 *
 * @author lhd
 */
@Component("balanceListener")
@AllArgsConstructor
public class BalancePayListener {
    private final UserExtensionService userExtensionService;
    private final UserBalanceLogService userBalanceLogService;
    private final UserLevelService userLevelService;
    private final PayService payService;
    private final ProductService productService;
    private final SkuService skuService;

    /**
     * 余额支付操作
     */
    @EventListener(BalancePayEvent.class)
    @Transactional(rollbackFor = Exception.class)
    public void balanceListener(BalancePayEvent event) {
        PayInfoDto payInfo = event.getPayInfo();
        PayInfoParam payInfoParam = event.getPayInfoParam();
        Double amount = payInfo.getPayAmount();
        UserExtension userExtension = userExtensionService.getOne(new LambdaQueryWrapper<UserExtension>().eq(UserExtension::getUserId, payInfo.getUserId()));
        if (Objects.isNull(userExtension)){
            payInfoParam.setType(2);
            //您的信息有误，请尝试刷新后再进行操作
            payInfoParam.setMessage(I18nMessage.getMessage("yami.information.is.wrong"));
            return;
        }
        if(Objects.isNull(userExtension.getTotalBalance()) || userExtension.getTotalBalance()<amount){
            payInfoParam.setType(3);
            payInfoParam.setMessage(I18nMessage.getMessage("yami.balance.is.insufficient"));
            return;
        }
        userExtension.setTotalBalance(Arith.sub(userExtension.getTotalBalance(), amount));
        userExtensionService.updateBalanceByVersion(userExtension);
        // 订单金额大于0，则添加余额记录
        if(amount > 0) {
            UserBalanceLog userBalanceLog = new UserBalanceLog();
            userBalanceLog.setUserId(userExtension.getUserId());
            userBalanceLog.setType(3);
            userBalanceLog.setIoType(0);
            userBalanceLog.setCreateTime(new Date());
            userBalanceLog.setChangeBalance(amount);
            userBalanceLog.setPayNo(payInfo.getPayNo());
            userBalanceLogService.save(userBalanceLog);
        }
        if(Objects.equals(payInfo.getType(), BuyType.LEVEL.value())) {
            userLevelService.paySuccess(payInfo.getPayNo());
        }else {
            //支付成功---根据内部订单号更新order settlement
            List<Order> orders = payService.paySuccess(payInfo.getPayNo(), "", PayType.BALANCE.value());

            // 移除缓存
            for (Order order : orders) {
                List<OrderItem> orderItems = order.getOrderItems();
                for (OrderItem orderItem : orderItems) {
                    productService.removeProdCacheByProdId(orderItem.getProdId(),LanguageEnum.LANGUAGE_ZH_CN.getLang());
                    productService.removeProdCacheByProdId(orderItem.getProdId(),LanguageEnum.LANGUAGE_EN.getLang());
                    skuService.removeSkuCacheBySkuIdAndLang(orderItem.getSkuId(), orderItem.getProdId(), LanguageEnum.LANGUAGE_ZH_CN.getLang());
                    skuService.removeSkuCacheBySkuIdAndLang(orderItem.getSkuId(), orderItem.getProdId(), LanguageEnum.LANGUAGE_EN.getLang());
                }
            }
        }
        payInfoParam.setType(1);
    }
}
